package main;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;

import layer_model.LayerModel;
import layer_model.LayerModelFactory;
import dao.FileIO;
import dao.PropertyIO;
import dao.SampleLoader;
import dto.Sample;
import dxo.SampleTo;
import evaluation.EvaluatorFactory;
import evaluation.LayerEvaluator;

public class LayerRecorder {

	public void proceed(Properties properties) {
		String filename = properties.getProperty("input_file");
		String labelfile = properties.getProperty("label_file");
		String modelType = properties.getProperty("modelType");
		String kListFile = properties.getProperty("klist_file");
		String evaluatorType = properties.getProperty("evaluator_type");
		LayerEvaluator evaluator = EvaluatorFactory.getEvaluator(evaluatorType);
		evaluator.initialize(properties);
		
		proceed(filename, labelfile, modelType, kListFile, evaluatorType, evaluator);
	}
	
	public void proceed(String filename, String labelfile, String modelType, String kListFile, String evaluatorType, LayerEvaluator evaluator) {
		System.out.println("proceeding " + filename + " ...");
		
		List<List<Sample>> sampleSplit = getSamples(filename, labelfile);
		List<Sample> trainSamples = sampleSplit.get(0);
		List<Sample> testSamples = sampleSplit.get(1);
		List<Integer> labelList = SampleTo.toLabel(testSamples);
		
		LayerModel model = LayerModelFactory.getModel(modelType);
		
		model.train(trainSamples);
		System.out.println("model :  " + model.dump());
		
		List<Integer> kList = new ArrayList<Integer>(testSamples.size());
		for(Sample testSample : testSamples) {
			kList.add(model.test(testSample));
		}
		
		// kList output
		printKList(kList, labelList, kListFile);
		
		// evaluation
		Map<String, Double> result = evaluator.evaluate(labelList, kList);
		
		for(Entry<String, Double> entry : result.entrySet()) {
			System.out.println(entry.getKey() + "=" + entry.getValue());
		}		
	}
	
	protected void printKList(List<Integer> kList, List<Integer> labelList, String filename) {
		List<String> list = new LinkedList<String>();
		
		Iterator<Integer> kItr = kList.iterator();
		Iterator<Integer> lItr = labelList.iterator();
		
		list.add("label\tk\n");
		while(kItr.hasNext()) {
			int k = kItr.next();
			int l = lItr.next();
			list.add(l + "\t" + k + "\n");
		}
		FileIO.writeFile(filename, list);
	}
	
	protected List<List<Sample>> getSamples (String filename, String labelfile) {
		List<Sample> samples = SampleLoader.getSamples(filename, labelfile);
		
		// split
		List<Sample> validation = samples;
		List<Sample> test = samples;
		
		List<List<Sample>> list = new ArrayList<List<Sample>>(2);
		list.add(validation);
		list.add(test);
		return list;
	}
	
	public static void main(String[] args) {
		if(args.length != 1) {
			return;
		}
		
		Properties properties = PropertyIO.load(args[0]);
		LayerRecorder main = new LayerRecorder();
		main.proceed(properties);
	}

}
